<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Task state segment</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Task_state_segment"> <link href="./mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Task_state_segment rootpage-Task_state_segment skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Task state segment</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<p>The <b>task state segment</b> (<b>TSS</b>) is a structure on <a href="X86" title="X86">x86</a>-based computers which holds information about a <a href="Task_(computing)" title="Task (computing)">task</a>. It is used by the <a href="Operating_system" title="Operating system">operating system</a> <a href="Kernel_(operating_system)" title="Kernel (operating system)">kernel</a> for task management. Specifically, the following information is stored in the TSS:
</p>
<ul><li><a href="Processor_register" title="Processor register">Processor register</a> state</li>
<li>I/O port permissions</li>
<li><a href="Protection_ring" title="Protection ring">Inner-privilege level</a> stack pointers</li>
<li>Previous TSS link</li>
<li>Debug state</li>
<li><a href="Shadow_stack" title="Shadow stack">Shadow stack</a> pointer</li></ul>
<p>All this information should be stored at specific locations within the TSS as specified in Volume 3(a), Chapter 8 of the <a href="IA-32" title="IA-32">IA-32</a> manuals.
</p>
<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="Location_of_the_TSS">Location of the TSS</h2></div>
<p>The TSS may reside anywhere in <a href="Computer_memory" title="Computer memory">memory</a>. A segment register called the task register (TR) holds a <a href="X86_memory_segmentation" title="X86 memory segmentation">segment selector</a> that points to a valid TSS segment descriptor which resides in the <a href="Global_Descriptor_Table" title="Global Descriptor Table">GDT</a> (a TSS descriptor may not reside in the <a href="Local_Descriptor_Table" class="mw-redirect" title="Local Descriptor Table">LDT</a>). Therefore, to use a TSS the following must be done by the operating system kernel:
</p>
<ol><li>Create a TSS descriptor entry in the GDT</li>
<li>Load the TR with the segment selector for that segment</li>
<li>Add information to the TSS in memory as needed</li></ol>
<p>For security purposes, the TSS should be placed in memory that is accessible only to the <a href="Kernel_(operating_system)" title="Kernel (operating system)">kernel</a>.
</p>
<div class="mw-heading mw-heading2"><h2 id="Task_register">Task register</h2></div>
<p>The TR register is a 16-bit register which holds a segment selector for the TSS. It may be loaded through the <a href="Load_task_register" title="Load task register">LTR</a> instruction. LTR is a privileged instruction and acts in a manner similar to other segment register loads. The task register has two parts: a portion visible and accessible by the programmer and an invisible one that is automatically loaded from the TSS descriptor.
</p>
<div class="mw-heading mw-heading2"><h2 id="Register_states">Register states</h2></div>
<p>The TSS may contain saved values of all the <a href="X86" title="X86">x86</a> registers. This is used for <a href="Context_switch" title="Context switch">task switching</a>. The <a href="Operating_system" title="Operating system">operating system</a> may load the TSS with the values of the registers that the new task needs and after executing a hardware task switch (such as with an IRET instruction) the x86 CPU will load the saved values from the TSS into the appropriate registers. Note that some modern operating systems such as <a href="Microsoft_Windows" title="Microsoft Windows">Windows</a> and <a href="Linux" title="Linux">Linux</a><sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup> do not use these fields in the TSS as they implement software task switching.
</p><p>Note that during a hardware task switch, certain fields of the <i>old</i> TSS are updated with the CPU's current register contents before the values from the <i>new</i> TSS are read. Thus some TSS fields are read/write, while others are read-only:
</p>
<ul><li><b>Read/Write fields</b>: read and written during a hardware task switch.
<ul><li>All general-purpose registers (<code>EAX</code>, <code>EBX</code>, <code>ECX</code>, <code>EDX</code>, <code>ESI</code>, <code>EDI</code>, <code>EBP</code>, <code>ESP</code>)</li>
<li>All segment registers (<code>CS</code>, <code>DS</code>, <code>ES</code>, <code>FS</code>, <code>GS</code>, <code>SS</code>)</li>
<li>Current execution state (<code>EIP</code>, <code>EFlags</code>)</li>
<li>The <code>Link</code> field in the <i>new</i> TSS, if the task switch was due to a <code>CALL</code> or <code>INT</code> rather than a <code>JMP</code>.</li></ul></li>
<li><b>Read-only fields</b>: read only when required, as indicated.
<ul><li>Control Register 3 (<code>CR3</code>), also known as the Page Directory Base Register (<code>PDBR</code>).
<dl><dd>Read during a hardware task switch.</dd></dl></li>
<li>The Local Descriptor Table register (<code>LDTR</code>)
<dl><dd>Read during a hardware task switch.</dd></dl></li>
<li>The three privilege-level stack pairs (<code>SS0:ESP0</code>, <code>SS1:ESP1</code>, <code>SS2:ESP2</code>)
<dl><dd>Read during an inter-level <code>CALL</code> or <code>INT</code> to establish a new stack.</dd></dl></li>
<li>The IO Port Bitmap pointer (<code>IOPB</code>) and the I/O Port Bitmap itself
<dl><dd>Read during an <code>IN</code>, <code>OUT</code>, <code>INS</code> or <code>OUTS</code> instruction if <code>CPL > IOPL</code> to confirm the instruction is legal (see <a href="#I/O_port_permissions">I/O port permissions</a> below).</dd></dl></li>
<li>debug trap (T)</li>
<li>SSP</li></ul></li></ul>
<p>The <code>PDBR</code> field is in fact the very first one read out of the new TSS: since a hardware task switch can also switch to a completely different page table mapping, all the other fields (especially the <code>LDTR</code>) are relative to the new mapping.
</p>
<div class="mw-heading mw-heading2"><h2 id="I/O_port_permissions">I/O port permissions</h2></div>
<p>The TSS contains a 16-bit pointer to I/O port permissions bitmap for the current <a href="Task_(computing)" title="Task (computing)">task</a>. This bitmap, usually set up by the operating system when a task is started, specifies individual ports to which the program should have access. The I/O bitmap is a <a href="Bit_array" title="Bit array">bit array</a> of port access permissions; if the program has permission to access a port, a "0" is stored at the corresponding bit index, and if the program does not have permission, a "1" is stored there. If the TSS’ segment limit is less than the full bitmap, all missing bits are assumed to be "1".
</p><p>The feature operates as follows: when a program issues an x86 I/O port instruction such as IN or OUT (see <a href="X86_instruction_listings" title="X86 instruction listings">x86 instruction listings</a> - and note that there are byte-, word- and dword-length versions), the hardware will do an I/O privilege level (IOPL) check to see if the program has access to all I/O ports. If the <a href="Current_privilege_level" class="mw-redirect" title="Current privilege level">Current Privilege Level (CPL)</a> of the program is numerically greater than the I/O Privilege level (IOPL) (the program is less-privileged than what the IOPL specifies), the program does not have I/O port access to all ports. The hardware will then check the I/O permissions bitmap in the TSS to see if that program can access the specific port(s) in the IN or OUT instruction. If (all the) relevant bit(s) in the I/O port permissions bitmap is/are clear, the program is allowed access to the port(s), and the instruction is allowed to execute. If (any of) the relevant bit(s) is/are set - or if (any of) the bit(s) is/are past the TSS’ segment limit - the program does not have access and the processor generates a <a href="General_protection_fault" title="General protection fault">general protection fault</a>. This feature allows operating systems to grant selective port access to user programs.
</p>
<div class="mw-heading mw-heading2"><h2 id="Inner-level_stack_pointers">Inner-level stack pointers</h2></div>
<p>The TSS contains 6 fields for specifying the new <a href="Stack_pointer" class="mw-redirect" title="Stack pointer">stack pointer</a> when a privilege level change happens. The field SS0 contains the stack segment selector for CPL=0, and the field ESP0/RSP0 contains the new ESP/RSP value for CPL=0. When an interrupt happens in protected (32-bit) mode, the <a href="X86" title="X86">x86</a> CPU will look in the TSS for SS0 and ESP0 and load their values into SS and ESP respectively. This allows for the kernel to use a different stack than the user program, and also have this stack be unique for each user program.
</p><p>A new feature introduced in the <a href="X86-64" title="X86-64">AMD64</a> extensions is called the Interrupt Stack Table (IST), which also resides in the TSS and contains logical (segment+offset) stack pointers. If an <a href="Interrupt_descriptor_table" title="Interrupt descriptor table">interrupt descriptor table</a> specifies an IST entry to use (there are 7), the processor will load the new stack from the IST instead. This allows known-good stacks to be used in case of serious errors (<a href="Non-maskable_interrupt" title="Non-maskable interrupt">NMI</a> or <a href="Double_fault" title="Double fault">Double fault</a> for example). Previously, the entry for the exception or interrupt in the IDT pointed to a task gate, causing the processor to switch to the task that is pointed by the task gate. The original register values were saved in the TSS current at the time the interrupt or exception occurred. The processor then set the registers, including SS:ESP, to a known value specified in the TSS and saved the selector to the previous TSS. The problem here is that hardware task switching is not supported on AMD64.
</p>
<div class="mw-heading mw-heading2"><h2 id="Previous_TSS_link">Previous TSS link</h2></div>
<p>This is a 16-bit selector which allows linking this TSS with the previous one. This is only used for hardware task switching. See the <a href="IA-32" title="IA-32">IA-32</a> manuals for details.
</p>
<div class="mw-heading mw-heading2"><h2 id="Use_of_TSS_in_Linux">Use of TSS in Linux</h2></div>
<p>Although a TSS could be created for each task running on the computer, <a href="Linux_kernel" title="Linux kernel">Linux kernel</a> only creates one TSS for each CPU and uses them for all tasks. This approach was selected as it provides easier portability to other architectures (for example, the <a href="X86-64" title="X86-64">AMD64</a> architecture does not support hardware task switches), and improved performance and flexibility. Linux only uses the I/O port permission bitmap and inner stack features of the TSS; the other features are only needed for hardware task switches, which the Linux kernel does not use.<sup id="cite_ref-2" class="reference"><a href="#cite_note-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="Exceptions_related_to_the_TSS">Exceptions related to the TSS</h2></div>
<p>The x86 <a href="Exception_handling" title="Exception handling">exception</a> vector 10 is called the Invalid TSS exception (#TS). It is issued by the processor whenever something goes wrong with the TSS access. For example, if an interrupt happens in CPL=3 and is transferring control to CPL=0, the TSS is used to extract SS0 and ESP0/RSP0 for the stack switch. If the task register holds a bad TSS selector, a #TS fault will be generated. The Invalid TSS exception should never happen during normal operating system operation and is always related to kernel bugs or hardware failure.
</p><p>For more details on TSS exceptions, see Volume 3(a), Chapter 6 of the <a href="IA-32" title="IA-32">IA-32</a> manual.<sup id="cite_ref-3" class="reference"><a href="#cite_note-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="TSS_in_x86-64_mode">TSS in x86-64 mode</h2></div>
<p>The <a href="X86-64" title="X86-64">x86-64</a> architecture does not support hardware task switches. However the TSS can still be used in a machine running in the 64 bit extended modes. In these modes the TSS is still useful as it stores:
</p>
<ol><li>The stack pointer addresses for each privilege level.</li>
<li>Pointer Addresses for the Interrupt Stack Table (The inner-level stack pointer section above, discusses the need for this).</li>
<li>Offset Address of the IO permission bitmap.</li></ol>
<p>Also, the task register is expanded in these modes to be able to hold a 64-bit base address.
</p>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1239543626">
/* start https://en.wikipedia.org/ */
.mw-parser-output .reflist{margin-bottom:0.5em;list-style-type:decimal}@media screen{.mw-parser-output .reflist{font-size:90%}}.mw-parser-output .reflist .references{font-size:100%;margin-bottom:0;list-style-type:inherit}.mw-parser-output .reflist-columns-2{column-width:30em}.mw-parser-output .reflist-columns-3{column-width:25em}.mw-parser-output .reflist-columns{margin-top:0.3em}.mw-parser-output .reflist-columns ol{margin-top:0}.mw-parser-output .reflist-columns li{page-break-inside:avoid;break-inside:avoid-column}.mw-parser-output .reflist-upper-alpha{list-style-type:upper-alpha}.mw-parser-output .reflist-upper-roman{list-style-type:upper-roman}.mw-parser-output .reflist-lower-alpha{list-style-type:lower-alpha}.mw-parser-output .reflist-lower-greek{list-style-type:lower-greek}.mw-parser-output .reflist-lower-roman{list-style-type:lower-roman}
/* end https://en.wikipedia.org/ */
</style><div class="reflist reflist-columns references-column-width" style="column-width: 30em;">
<ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><b><a href="#cite_ref-1">^</a></b></span> <span class="reference-text"><style data-mw-deduplicate="TemplateStyles:r1238218222">
/* start https://en.wikipedia.org/ */
.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}.mw-parser-output .citation q{quotes:"\"""\"""'""'"}.mw-parser-output .citation:target{background-color:rgba(0,127,255,0.133)}.mw-parser-output .id-lock-free.id-lock-free a{background:url("./mw/Lock-green.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-limited.id-lock-limited a,.mw-parser-output .id-lock-registration.id-lock-registration a{background:url("./mw/Lock-gray-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-subscription.id-lock-subscription a{background:url("./mw/Lock-red-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .cs1-ws-icon a{background:url("./mw/Wikisource-logo.svg")right 0.1em center/12px no-repeat}body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-free a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-limited a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-registration a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-subscription a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .cs1-ws-icon a{background-size:contain;padding:0 1em 0 0}.mw-parser-output .cs1-code{color:inherit;background:inherit;border:none;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;color:var(--color-error,#d33)}.mw-parser-output .cs1-visible-error{color:var(--color-error,#d33)}.mw-parser-output .cs1-maint{display:none;color:#085;margin-left:0.3em}.mw-parser-output .cs1-kern-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}@media screen{.mw-parser-output .cs1-format{font-size:95%}html.skin-theme-clientpref-night .mw-parser-output .cs1-maint{color:#18911f}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .cs1-maint{color:#18911f}}
/* end https://en.wikipedia.org/ */
</style><cite id="CITEREFBovetCesatí2006" class="citation book cs1">Bovet, Daniel Pierre; Cesatí, Marco (2006). <a rel="nofollow" class="external text" href="https://books.google.com/books?id=h0lltXyJ8aIC&q=Linux+hardware+TSS&pg=PA104"><i>Understanding the Linux Kernel, Third Edition</i></a>. <a href="O'Reilly_Media" title="O'Reilly Media">O'Reilly Media</a>. p. 104. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a> <bdi>978-0-596-00565-8</bdi><span class="reference-accessdate">. Retrieved <span class="nowrap">2009-11-23</span></span>.</cite></span>
</li>
<li id="cite_note-2"><span class="mw-cite-backlink"><b><a href="#cite_ref-2">^</a></b></span> <span class="reference-text"><cite id="CITEREFDaniel_P._BovetMarco_Cesati2006" class="citation book cs1">Daniel P. Bovet; Marco Cesati (2006). <a rel="nofollow" class="external text" href="https://books.google.com/books?id=h0lltXyJ8aIC&q=tss+linux&pg=PT122"><i>Understanding the Linux Kernel</i></a>. O'Reilly. p. 104. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a> <bdi>9780596554910</bdi><span class="reference-accessdate">. Retrieved <span class="nowrap">2014-02-25</span></span>.</cite></span>
</li>
<li id="cite_note-3"><span class="mw-cite-backlink"><b><a href="#cite_ref-3">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html">"Intel 64 and IA-32 Architectures Software Developer's Manual Volume 3a"</a><span class="reference-accessdate">. Retrieved <span class="nowrap">21 May</span> 2012</span>.</cite></span>
</li>
</ol></div>
<div class="mw-heading mw-heading2"><h2 id="External_links">External links</h2></div>
<ul><li><a rel="nofollow" class="external text" href="http://wiki.osdev.org/User:Johnburger/Demo">Demonstration program using TSSes</a></li></ul></div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2025-06-23" href="https://en.wikipedia.org/wiki/?title=Task_state_segment&oldid=1296951006">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
</body></html>